package com.bizfx.component.controls
{	
	import flash.display.DisplayObject;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.utils.describeType;
	
	import com.bizfx.component.views.BaseView;
	import com.bizfx.component.views.IView;
	import com.bizfx.errors.NoAlertError;
	import com.bizfx.events.PopUpWindowEvent;
	import com.bizfx.events.ViewCommandEvent;
	import com.bizfx.utils.StringUtils;
	
	import mx.containers.TitleWindow;
	import mx.controls.Alert;
	import mx.core.Application;
	import mx.events.CloseEvent;
	import mx.managers.PopUpManager;

	[Event(name="popUpWindowShowed", type="com.bizfx.events.PopUpWindowEvent")]

	[Event(name="popUpWindowShowing", type="com.bizfx.events.PopUpWindowEvent")]

	public class PopUpWindow extends EventDispatcher {
		
		private var window:TitleWindow;
		
		private var _title:String;
		
		private var _view:IView;
		[Bindable("viewChanged")]
		public function get view():IView {
			return _view;
		}
		
		public function set view(value:IView):void {
			if (this._view != value) {
				if (this._view) {
					this.view.removeEventListener(ViewCommandEvent.ViewCommand_Raise, viewCommandRaiseHandler);
				}
				this._view = value;
				if (this._view) {
					this.view.addEventListener(ViewCommandEvent.ViewCommand_Raise, viewCommandRaiseHandler);
				}
				this.dispatchEvent(new Event("viewChanged"));
			}
		}
		
		[Bindable]
		public function get title():String {
			return this._title;
		}
		
		public function set title(value:String):void {
			this._title = value;
		}
		
		private var _icon:Class;

		[Bindable]
		public function get icon():Class {
			if (_icon == null) {
				if (this.view)
					return this.view["icon"];
			}
			return _icon;
		}

		public function set icon(value:Class):void {
			_icon = value;
		}

		public function PopUpWindow() {
			super();
		}
		
		private function viewCommandRaiseHandler(event:ViewCommandEvent):void {
			try {
				var sender:IView = event.target as IView;
				
//				var methodName:String = "view_" + event.viewCommand.commandKey + "Handler";
//				if (!StringUtils.isNullOrEmpty(sender.viewKey)) {
//					methodName = "view_" + sender.viewKey + "_" + event.viewCommand.commandKey + "Handler";
//				}
				var methodName:String = "";
				var xmlList:XMLList = describeType(this).method.metadata.(@name == "ViewCommandHandler").arg.(@key == "commandKey" && @value == event.viewCommand.commandKey);
				if (xmlList.length() > 0) {
					var xl:XMLList = xmlList[0].parent().arg.(@key == "view")
					if (xl.length() > 0) {
						if (xl[0].@value == ((sender.viewKey == null)?"":sender.viewKey)) {
							methodName = xmlList[0].parent().parent().@name;
						}
					} else {
						methodName = xmlList[0].parent().parent().@name;
					}
				}
				
				if (!StringUtils.isNullOrEmpty(methodName) && this.hasOwnProperty(methodName)) {
					var eventMethod:Function = this[methodName];
					if (eventMethod != null) {
						callEventMethod(eventMethod, event);
					}
				}
				else {
					if (event.viewCommand.requestedHandler) {
						var errorMsg:String = "没有处理视图事件“" + event.type + "”的方法【" + methodName + "】。" 
						Alert.show(errorMsg, "错 误", 4, Sprite(Application.application));	
					} else {
					}
				}
			} catch (e:NoAlertError) {
				trace(e.message);
			} catch (e:Error) {
				Alert.show(e.message, "错 误", 4, Sprite(Application.application));
			}
		}
		
		protected function callEventMethod(funciton:Function, event:ViewCommandEvent):void {
			funciton.call(this, event);
		}
		
		public function show(parent:DisplayObject=null):void {
			if (!window) {
				window = new TitleWindow();
				window.title = this.title;
				window.showCloseButton = true;
				window.addEventListener(CloseEvent.CLOSE, chooserCloseHandler);
				if (view) {
					window.addChild(DisplayObject(view));
				}
				if (this.icon) {
					window.titleIcon = this.icon;
				}
			}
			this.dispatchEvent(new PopUpWindowEvent(PopUpWindowEvent.PopUpWindow_Showing));
			
			if (parent) {
				PopUpManager.addPopUp(window, parent, true);
			} else {
				PopUpManager.addPopUp(window, DisplayObject(Application.application), true);
			}
				
			PopUpManager.centerPopUp(window);
			this.dispatchEvent(new PopUpWindowEvent(PopUpWindowEvent.PopUpWindow_Showed));
		}
		
		public function hide():void {
			PopUpManager.removePopUp(window);
		}
		
		private function chooserCloseHandler(event:CloseEvent):void {
			hide();
		}
	}
}